package shopcart;

import enums.ShopCartStatus;
import goods.Goods;
import helper.CacheCallBack;
import helper.CacheHelper;
import models.constants.DeletedStatus;
import models.merchant.Merchant;
import models.weixin.WebUser;
import play.Logger;
import play.db.jpa.JPA;
import play.db.jpa.Model;
import product.Product;
import product.merchant.ProductSpecMerchant;
import util.common.UStringUtil;

import javax.persistence.*;
import java.util.Date;
import java.util.List;


/**
 * 购物车
 */
@Entity
@Table(name = "shop_carts")
public class ShopCart extends Model {
    public static final String CACHE_SHOP_CART_ID = "ULC_CACHE_SHOPCART_ID_";
    public static final String CACHE_SHOP_CART_COUNT = "ULC_CACHE_SHOPCART_COUNT_";


    /**
     * 前端用户
     */
    @JoinColumn(name = "web_user_id", nullable = true)
    @ManyToOne
    public WebUser webUser;

    /**
     * 所属商户
     */
   /* @JoinColumn(name = "merchant_id", nullable = true)
    @ManyToOne
    public Merchant merchant;*/

    /**
     * 商品信息
     */
    @JoinColumn(name = "goods_id", nullable = true)
    @ManyToOne
    public Goods goods;


    /**
     * 商品名称
     */
    @Column(name = "goods_name")
    public String goodsName;

    /**
     * 购买数量
     */
    @Column(name = "buy_number")
    public Integer buyNumber;


    /**
     * 销售单价
     */
    @Column(name = "sale_price")
    public Double salePrice;

    /**
     * 购物车商品状态
     */
    @Column(name = "status")
    @Enumerated(EnumType.STRING)
    public ShopCartStatus status;


    /**
     * 逻辑删除状态
     */
    @Column(name = "deleted")
    @Enumerated(EnumType.ORDINAL)
    public DeletedStatus deleted;


    /**
     * 购物篮创建时间
     */
    @Column(name = "created_at")
    public Date createdAt;

    public ShopCart(){

    }
    public ShopCart(Product product, WebUser webUser, Integer count){
        this.webUser = webUser;
        this.goods = product.findGoods();
        this.goodsName = product.name;
        this.buyNumber = count;
        this.salePrice = product.merchantPrice == null ?0.00:product.merchantPrice;
        this.createdAt = new Date();
        this.deleted = DeletedStatus.UN_DELETED;
    }

    public ShopCart(Product product,WebUser webUser,Integer count,Goods goods){
        this.webUser = webUser;
        this.goods = product.findGoods();
        this.goodsName = product.name;
        this.buyNumber = count;
        this.salePrice = goods.salePrice;
        this.createdAt = new Date();
        this.deleted = DeletedStatus.UN_DELETED;
    }


    public ShopCart(ProductSpecMerchant productSpecMerchant,WebUser webUser,Integer count,Merchant merchant){
        this.webUser = webUser;
        this.goods = productSpecMerchant.findGoods(webUser);
        this.goodsName = productSpecMerchant.productSpec.product.name;
        this.buyNumber = count;
        this.salePrice = productSpecMerchant.merchantPrice == null ?productSpecMerchant.productSpec.product.marketPrice:productSpecMerchant.merchantPrice;
        this.createdAt = new Date();
        this.deleted = DeletedStatus.UN_DELETED;
    }

    public ShopCart(ProductSpecMerchant productSpecMerchant,WebUser webUser,Integer count,Goods goods){
        this.webUser = webUser;
        this.goods = productSpecMerchant.findGoods(webUser);
        this.goodsName = productSpecMerchant.productSpec.product.name;
        this.buyNumber = count;
        this.salePrice = goods.salePrice;
        this.createdAt = new Date();
        this.deleted = DeletedStatus.UN_DELETED;
    }


    /**
     * 从缓存中根据ID查实体
     * @param id
     * @return
     */
    public static ShopCart findByCacheId(final long id) {
        return CacheHelper.getCache(CACHE_SHOP_CART_ID+id, new CacheCallBack<ShopCart>() {
            @Override
            public ShopCart loadData() {
                return ShopCart.find("deleted = ?1 and id = ?2", DeletedStatus.UN_DELETED, id).first();
            }
        });
    }
    public static Boolean delete(Long id) {
        ShopCart item = ShopCart.findById(id);
        if (item == null) {
            return Boolean.FALSE;
        }
        item.deleted = DeletedStatus.DELETED;
        item.save();
        return Boolean.TRUE;
    }
    public void changeToNumber(Integer count){
        this.buyNumber = count;
        if(count == null || count == 0){
            this.deleted = DeletedStatus.DELETED;
            this.save();
        }else {
            this.save();
        }
    }

    /**
     * 产品 加入购物车
     * @param webUser
     * @param product
     * @param count
     */
    public static void addProduct(WebUser webUser , ProductSpecMerchant product, Integer count) {
        Goods goods = product.findGoods(webUser);
        ShopCart shopCart = ShopCart.find("goods = ?1 and deleted = ?2" , goods , DeletedStatus.UN_DELETED).first();
        if(shopCart == null) {
            shopCart = new ShopCart();
            shopCart.goods = goods;
            shopCart.goodsName = product.productSpec.product.name;
            shopCart.buyNumber = count;
            shopCart.webUser = webUser;
            shopCart.deleted = DeletedStatus.UN_DELETED;
            shopCart.createdAt = new Date();
        } else {
            shopCart.buyNumber = count;
            shopCart.save();
        }
    }

    /**
     * 根据产品及用户查询购物车是否有该商品
     * @param productId
     * @return
     */
    public static ShopCart findByProductIdAndUser(Long productId , WebUser webUser ) {
        return ShopCart.find("goods.serialId = ?1  and deleted = ?2 and  webUser = ?3 and status != ?4" , productId  , DeletedStatus.UN_DELETED , webUser, ShopCartStatus.BUY).first();
    }

    /**
     * 根据产品及用户查询购物车是否有该商品
     * @param goods
     * @return
     */
    public static ShopCart findByProductIdAndUser(Goods goods , WebUser webUser ) {
        return ShopCart.find("goods = ?1  and deleted = ?2 and  webUser = ?3" , goods  , DeletedStatus.UN_DELETED ,webUser).first();
    }

    public static List<ShopCart> findShopCartByUserAndMerchant( WebUser webUser){
        return ShopCart.find(" deleted = ?1    and webUser = ?2" ,DeletedStatus.UN_DELETED,webUser).fetch();
    }

    public static List<ShopCart> findShopCartByUserAndMerchant( WebUser webUser , ShopCartStatus shopCartStatus){
        return ShopCart.find(" deleted = ?1   and webUser = ?2 and status=?3" ,DeletedStatus.UN_DELETED,webUser,shopCartStatus).fetch();
    }

    public static long findShopCartSize( WebUser webUser){
        return ShopCart.count("deleted = ?1  and webUser = ?2" ,DeletedStatus.UN_DELETED,webUser );
    }

    public static Double sumByWebUserAndMerchant(WebUser webUser ) {
        StringBuilder hql = new StringBuilder("select sum(s.sale_price * s.buy_number) from shop_carts s where web_user_id = "+webUser.id+"  and deleted = 0");
        Query query = JPA.em().createNativeQuery(hql.toString());
        List queryList = query.getResultList();
        Logger.info("queryList : %s" , queryList.get(0));
        return (Double) (queryList.get(0) == null ? 0d : queryList.get(0));
    }
    public static List<ShopCart> findShopCartByChecked(String carts){
        return ShopCart.find(" deleted = ?1 and id in ( "+carts+") ",DeletedStatus.UN_DELETED).fetch();
    }

    public static void deletedByGoods(Goods goods) {
        StringBuilder hql = new StringBuilder("update shop_carts sc set sc.deleted = 1 where sc.goods_id=" + goods.id);
        Logger.info("deletedByGoods : %s" , hql.toString());
        JPA.em().createNativeQuery(hql.toString()).executeUpdate();
    }

    /**
     * 按shopCart 的ids 删除
     * @param shopCardIds
     */
    public static void deleteByShopCartIds(Long[] shopCardIds){
        String str = UStringUtil.concatStr(",",shopCardIds);
        StringBuilder hql = new StringBuilder("update shop_carts sc set sc.deleted = 1 where sc.id in ("+str+")");
        JPA.em().createNativeQuery(hql.toString()).executeUpdate();
    }


}
